package com.xhwl.centiotdata.action.pedestrian.impl;

import com.xhwl.centiotdata.action.pedestrian.IPedestrianAction;
import com.xhwl.centiotdata.handler.account.AccountFactory;
import com.xhwl.centiotdata.handler.account.AccountHandler;
import com.xhwl.centiotdata.handler.org.OrgFactory;
import com.xhwl.centiotdata.handler.org.OrgHandler;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationFactory;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationHandler;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.pojo.enums.pedestrian.PedestrianMethodEnum;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.cent.IPedestrianCentService;
import com.xhwl.centiotdata.service.impl.AccountServiceImpl;
import com.xhwl.centiotdata.service.integrateconfig.PedestrianIntegrationConfig;
import com.xhwl.centiotdata.suppliersystem.bailian.PedestrianBaiLianHandler;
import com.xhwl.common.dto.auth.PedestrianAuthDTO;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.pedes.DoorActionDTO;
import com.xhwl.common.dto.cent.pedes.OpenDoorRecordDTO;
import com.xhwl.common.dto.cent.sdata.AccountDTO;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.auth.AuthAccountMapping;
import com.xhwl.common.pojo.cent.sdata.Organization;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffDTO;
import com.xhwl.common.query.cent.device.DeviceQuery;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestPart;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/09/07/ 11:44
 */
@Service
public class PedestrianActionImpl implements IPedestrianAction {
    private static final Logger log = LoggerFactory.getLogger(PedestrianBaiLianHandler.class);

    @Autowired
    private PedestrianIntegrationConfig integrationConfig;
    @Autowired
    private IDeviceCentService deviceCentService;
    @Autowired
    private AccountServiceImpl accountService;
    @Autowired
    private IAuthAccountCentService authAccountCentService;
    @Autowired
    private IPedestrianCentService pedestrianCentService;

    private static final String DEVICE_OFF = "0";

    @Override
    public ResultJson openDoor(DoorActionDTO doorActionDTO) {
        List<PedestrianIntegrationConfigDTO> configDTOList = integrationConfig.getIntegrationConfig(null).get(PedestrianMethodEnum.OPEN_DOOR.getId());
        if (CollectionUtils.isEmpty(configDTOList)) {
            return ResultJson.fail("未找到配置");
        }
        DeviceQuery deviceQuery = new DeviceQuery();
        deviceQuery.setId(doorActionDTO.getId());
        List<DeviceDTO> deviceDTOList = deviceCentService.list(null, deviceQuery);
        if (CollectionUtils.isEmpty(deviceDTOList)) {
            return ResultJson.fail("未找到设备");
        }
        DeviceDTO deviceDTO = deviceDTOList.get(0);

        if(deviceDTO.getOnlineStatus() == Integer.parseInt(DEVICE_OFF)){
            log.info("设备状态为{}",deviceDTO.getDeviceStatus());
            return ResultJson.fail("设备离线，无法遥控操作");
        }
        List<PedestrianIntegrationConfigDTO> integrationConfigDTOList = configDTOList.stream()
                .filter(configDTO -> configDTO.getProjectId().equals(deviceDTO.getProjectId()) && configDTO.getProductId().equals(deviceDTO.getProductId()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(integrationConfigDTOList)) {
            return ResultJson.fail("未找到系统配置");
        }

        PedestrianIntegrationHandler handler = PedestrianIntegrationFactory.getInvokeStrategy(deviceDTO.getProductId());
        if (handler == null) {
            return ResultJson.fail("未找到处理方式");
        }
        return handler.openDoor(integrationConfigDTOList.get(0), deviceDTO, doorActionDTO.getDoorAction());
    }
    @Override
    public ResultJson addUser(PedestrianAuthDTO pedestrianAuthDTO) {
        List<PedestrianIntegrationConfigDTO> configDTOList = integrationConfig.getIntegrationConfig(null).get(PedestrianMethodEnum.RECORD.getId());
        if (CollectionUtils.isEmpty(configDTOList)) {
            return ResultJson.fail("未找到配置");
        }

        if (CollectionUtils.isEmpty(pedestrianAuthDTO.getCardNumberList()) && StringUtils.isEmpty(pedestrianAuthDTO.getCardNumber())) {
            return ResultJson.fail("无卡号");
        }

        List<PedestrianIntegrationConfigDTO> integrationConfigDTOList = configDTOList.stream()
                .filter(configDTO -> configDTO.getProjectId().equals(pedestrianAuthDTO.getProjectId()))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(integrationConfigDTOList)) {
            return ResultJson.fail("未找到系统配置");
        }

        // 如果人脸照片为空 查询主数据的人脸图片
        if(StringUtils.isEmpty(pedestrianAuthDTO.getFaceUrl())) {
            List<AccountDTO> accountDTOList = accountService.queryAccount(pedestrianAuthDTO.getProjectId(), Arrays.asList(pedestrianAuthDTO.getSourceId()));
            AccountDTO accountDTO = accountDTOList.get(0);
            pedestrianAuthDTO.setFaceUrl(accountDTO.getFaceUrl());
        }
        integrationConfigDTOList.forEach(integrationConfig->{
            PedestrianIntegrationHandler handler = PedestrianIntegrationFactory.getInvokeStrategy(integrationConfig.getProductId());
            if (handler != null) {
                AuthAccountMapping accountMapping = authAccountCentService.query(integrationConfig.getProjectId(), pedestrianAuthDTO.getSourceId(), integrationConfig.getProductId());
                if(accountMapping!=null && !StringUtils.isEmpty(accountMapping.getOpenId())){
                    pedestrianAuthDTO.setUserOpenId(accountMapping.getOpenId());
                    pedestrianAuthDTO.setUserOpenIds(Collections.singletonList(accountMapping.getOpenId()));
                    pedestrianAuthDTO.setProductId(accountMapping.getProductId());
                }
                //卡号同步到第三方时 需要转换
                List<String> cardNumberList = merge(pedestrianAuthDTO.getCardNumberList(), pedestrianAuthDTO.getCardNumber());
                Map<Integer, Map<String, String>> carNumberMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(cardNumberList)) {
                    carNumberMap = pedestrianCentService.cardTransition(pedestrianAuthDTO.getProjectId(), cardNumberList);
                }
                Map<String, String> carMap = carNumberMap.get(accountMapping.getProductId());
                if (!CollectionUtils.isEmpty(carMap)) {
                    pedestrianAuthDTO.setCardNumber(carMap.get(pedestrianAuthDTO.getCardNumber()));
                    pedestrianAuthDTO.setCardNumberList(new ArrayList<>(carMap.values()));
                }
                handler.addUser(integrationConfig, pedestrianAuthDTO);
            }
        });
        return ResultJson.success();
    }

    private List<String> merge(List<String> list, String str) {
        if (list == null) {
            if (StringUtils.isEmpty(str)) {
                return null;
            }
            list = new ArrayList<>();
            list.add(str);
            return list;
        }
        if (!StringUtils.isEmpty(str) && !list.contains(str)) {
            list.add(str);
        }
        return list;
    }

    @Override
    public ResultJson queryInsideQrCode(OpenDoorRecordDTO openDoorRecordDTO){
//        Integer projectId,
//        @RequestPart Integer accountId,
//        @RequestPart Integer productId, @RequestPart String openCode
        log.info("openDoorRecordDTO:"+openDoorRecordDTO);
        PedestrianIntegrationHandler handler = PedestrianIntegrationFactory.getInvokeStrategy(openDoorRecordDTO.getProductId() );
        log.info("handler:"+handler);
        List<PedestrianIntegrationConfigDTO> configDTOList = integrationConfig.getIntegrationConfig(null).get(PedestrianMethodEnum.INSIDE_QR_CODE.getId());
        log.info("configDTOList"+configDTOList);
        if (CollectionUtils.isEmpty(configDTOList)) {
            return ResultJson.fail("未找到配置");
        }
        List<PedestrianIntegrationConfigDTO> integrationConfigDTOList = configDTOList.stream()
                .filter(configDTO -> configDTO.getProjectId().equals(openDoorRecordDTO.getProjectId()) && configDTO.getProductId().equals(openDoorRecordDTO.getProductId()))
                .collect(Collectors.toList());
        log.info("integrationConfigDTOList"+integrationConfigDTOList);
        if (CollectionUtils.isEmpty(integrationConfigDTOList)) {
            return ResultJson.fail("未找到系统配置");
        }
        return handler.getInsideQrCode (integrationConfigDTOList.get(0), openDoorRecordDTO);

    }

    @Override
    public String syncUser(StaffDTO staffDTO, Integer projectId) {
        List<PedestrianIntegrationConfigDTO> configDTOList = integrationConfig.getIntegrationConfig(null).get(PedestrianMethodEnum.SYNC_USER.getId());

        if (CollectionUtils.isEmpty(configDTOList)) {
            return "";
        }
        List<PedestrianIntegrationConfigDTO> integrationConfigDTOList = configDTOList.stream()
                .filter(configDTO -> configDTO.getProjectId().equals(projectId))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(integrationConfigDTOList)) {
            return "";
        }
        AccountHandler handler = AccountFactory.getInvokeStrategy(integrationConfigDTOList.get(0).getProductId());
        return handler.syncUser(integrationConfigDTOList.get(0), staffDTO);
    }

    @Override
    public String syncOrg(List<Organization> organizationList, Integer projectId) {
        List<PedestrianIntegrationConfigDTO> configDTOList = integrationConfig.getIntegrationConfig(null).get(PedestrianMethodEnum.SYNC_USER.getId());
        if (CollectionUtils.isEmpty(configDTOList)) {
            return "";
        }
        List<PedestrianIntegrationConfigDTO> integrationConfigDTOList = configDTOList.stream()
                .filter(configDTO -> configDTO.getProjectId().equals(projectId))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(integrationConfigDTOList)) {
            return "";
        }
        OrgHandler handler = OrgFactory.getInvokeStrategy(integrationConfigDTOList.get(0).getProductId());
        return handler.syncOrg(integrationConfigDTOList.get(0), organizationList);
    }
}
